﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace InfoPathExtractionRules
{
    public class CurrentFormData
    {
        private int canaryIndex = Index.CanaryValue;

        /// <summary>
        /// Index of the item in g_objCurrentFormData javascript array
        /// for SP2 servers
        /// </summary>
        public static class Index
        {
            public const int
                PostbackCounter = 2,
                EditingSessionId = 3,
                SolutionId = 4,
                CanaryValue = 27,
                NumberOfItems = 28
            ;
        }

        /// <summary>
        /// Index of the item in g_objCurrentFormData javascript array
        /// for SP1 servers
        /// </summary>
        public static class IndexSP1
        {
            public const int
                PostbackCounter = 2,
                EditingSessionId = 3,
                SolutionId = 4,
                CanaryValue = 25,
                NumberOfItems = 26
            ;
        }

        /// <summary>
        /// Index of the item in g_objCurrentFormData javascript array
        /// for RTM servers
        /// </summary>
        public static class IndexRTM
        {
            public const int
                PostbackCounter = 2,
                EditingSessionId = 3,
                SolutionId = 4,
                CanaryValue = 24,
                NumberOfItems = 25
            ;
        }

        public const string ContextParameterName = "CurrentFormData";
        private string[] data = new string[Index.NumberOfItems];

        public string Canary
        {
            get
            {
                string canary = data[canaryIndex].Trim('"');
                return Regex.Unescape(canary);
            }
            set
            {
                data[canaryIndex] = value;
            }
        }

        public string EditingSessionId
        {
            get
            {
                return data[Index.EditingSessionId].Trim('"');
            }
            set
            {
                data[Index.EditingSessionId] = value;
            }
        }

        public string SolutionId
        {
            get
            {
                return data[Index.SolutionId].Trim('"');
            }
            set
            {
                data[Index.SolutionId] = value;
            }
        }

        public CurrentFormData(string javascriptArray)
        {
            int startIndex = 0;
            int itemIndex = 0;
            int nesting = 0;
            char c;
            // Parse the items in the array
            // The items in the array are separated by commas,
            // but the array can contain other arrays which can contain commas
            for (int i = 0; i < javascriptArray.Length; i++)
            {
                c = javascriptArray[i];

                // Take into account arrays within this array
                if (c == '[')
                {
                    nesting++;
                }
                else if (c == ']')
                {
                    nesting--;
                }

                // If we are not in an internal array and
                // we reached a comma or the end of the string,
                // then we parsed an item
                if (nesting == 0 && (c == ',' || i == javascriptArray.Length - 1))
                {
                    string item = IPExtractionUtil.getSubString(javascriptArray, startIndex, i);
                    item = item.Trim(',');
                    data[itemIndex] = item;

                    startIndex = i + 1;
                    itemIndex++;
                }
            }

            // HACK for SP1 version
            if (itemIndex == IndexSP1.NumberOfItems)
                canaryIndex = IndexSP1.CanaryValue;
            // HACK for RTM version
            else if (itemIndex == IndexRTM.NumberOfItems)
                canaryIndex = IndexRTM.CanaryValue;
        }
    }
}
